﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Controls;
using System.Globalization;
using produccion.modelo;
using produccion.AccesoDatos;
using produccion.clases;
using System.Windows.Input;
using System.Collections.Specialized;

namespace produccion.vistamodelo
{
    class VMMantenimientoPrecios : ViewModelBase
    {
        #region Campos

            private List<CLSLISPREP> _lisprecio = new List<CLSLISPREP>();
            private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();

        #endregion

        #region constructor

            public VMMantenimientoPrecios()
            {
                try
                {
                    consultarPrecios();
                    lisprecios.CollectionChanged += OnCollectionChanged;

                    if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                    {
                        MDOgeneral.conectar();
                    }
                    strTituloVentana = "Mantenimiento de precios - Usuario: " + MDOgeneral.usuario + " - [FRMMantenimientodePrecios]";
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

        #endregion

        #region Interfaces publicas

            private string _strTituloVentana;
            public string strTituloVentana
            {
                get { return _strTituloVentana; }
                set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
            }

            public List<CLSLISPREP> lisprecio
            {
                get { return _lisprecio; }
                set { _lisprecio = value; base.OnPropertyChanged("lisprecio"); }
            }

            private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
            public MDOgeneral.mensaje msn
            {
                get { return _msn; }
                set { _msn = value; base.OnPropertyChanged("msn"); }
            }

            private ObservableCollection<VMPrecios> _lisprecios = new ObservableCollection<VMPrecios>();
            public ObservableCollection<VMPrecios> lisprecios
            {
                get { return _lisprecios; }
                set { _lisprecios = value; base.OnPropertyChanged("lisprecios"); }
            }

            private VMPrecios _selprecio;
            public VMPrecios selprecio
            {
                get { return _selprecio; }
                set { _selprecio = value; base.OnPropertyChanged("selprecio"); }
            }

            private Boolean _logValido;
            public Boolean logValido
            {
                get { return _logValido; }
                set { _logValido = value; base.OnPropertyChanged("logValido"); }
            }

        #endregion

        #region Comandos

            RelayCommand _cmdSalir;
            public ICommand cmdSalir
            {
                get
                {
                    if (_cmdSalir == null)
                    {
                        _cmdSalir = new RelayCommand(Salir);
                    }
                    return _cmdSalir;
                }
            }

            RelayCommand _cmdEliminar;
            public ICommand cmdEliminar
            { 
                get
                {
                    if (_cmdEliminar == null)
                    {
                        _cmdEliminar = new RelayCommand(r => eliminarPrecio());
                    }
                    return _cmdEliminar;
                }
            }

            RelayCommand _cmdGrabar;
            public ICommand cmdGrabar
            {
                get
                {
                    if (_cmdGrabar == null)
                    {
                        _cmdGrabar = new RelayCommand(r => grabarPrecio());
                    }
                    return _cmdGrabar;
                }
            }

        #endregion

        #region Metodos
            
            public void consultarPrecios()
            {
                try
                {
                    CLSLISPREP lispre = new CLSLISPREP();
                    lisprecio = lispre.listarPrecios();
                    List<VMPrecios> all = (from pre in lisprecio select new VMPrecios(pre)).ToList();
                    foreach (VMPrecios pre in all)
                    {
                        pre.validarPrecio += validaPrecio;
                        pre.PropertyChanged += OnPropertyChanged;
                    }

                    lisprecios = new ObservableCollection<VMPrecios>(all);
                    lisprecios.CollectionChanged += OnCollectionChanged;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                logValido = ((from pre in lisprecios where pre.IsValid.Equals(false) select pre.IsValid).ToList().Count()) > 0 ? true : false;
            }

            void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                try
                {
                    if (e.NewItems != null && e.NewItems.Count > 0)
                    {
                        foreach (VMPrecios cau in e.NewItems)
                        {
                            cau.validarPrecio += validaPrecio;
                            cau.PropertyChanged += OnPropertyChanged;
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public string validaPrecio(string strCodigoPrecio)
            {
                try
                {
                    int i = (from pre in lisprecios where pre.codlis_pre.Trim().Equals(strCodigoPrecio.Trim()) select pre).ToList().Count();
                    if (i > 1)
                    {
                        return "Código de lista de precios ya existe";
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            private void grabarPrecio()
            {
                try
                {
                    List<CLSLISPREP> lstAgregar = (from pre in lisprecios where pre.agregar.Equals(true) select pre.getPrecios()).ToList();
                    List<CLSLISPREP> lstActualizar = (from pre in lisprecios where pre.actualizar.Equals(true) select pre.getPrecios()).ToList();
                    List<CLSLISPREP> lstEliminar = (from pre in lisprecios where pre.eliminar.Equals(true) select pre.getPrecios()).ToList();

                    if (_repositorio.guardarPrecios(lstActualizar, lstEliminar, lstAgregar))
                    {
                        msn.texto = "La información de lista de precios fue guardada exitosamente.";
                        msn.tipo = true;
                        consultarPrecios();
                    }
                    else
                    {
                        msn.texto = "La información de lista de precios no se pudo grabar.";
                        msn.tipo = false;
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            private void eliminarPrecio()
            {
                try
                {
                    if (selprecio.agregar)
                        lisprecios.Remove(selprecio);
                    else
                        selprecio.eliminar = !selprecio.eliminar;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void Salir(Object frmformulario)
            {
                ((Window)frmformulario).Close();
            }

        #endregion

        #region Vistas-Modelo

            public class VMPrecios : ViewModelBase, IDataErrorInfo
            {

                #region Campos
            
                    private CLSLISPREP _precios = new CLSLISPREP();
                    public delegate string validarCodigoPrecio(string codlis_pre);

                #endregion

                #region Constructor

                    public VMPrecios(CLSLISPREP precios)
                    {
                        _precios = precios;
                    }

                    public VMPrecios()
                    {
                        agregar = true;
                        base.OnPropertyChanged("codlis_pre");
                       
                    }
                #endregion

                #region Metodos

                    public CLSLISPREP getPrecios()
                    {
                        return _precios;
                    }

                #endregion

                #region Interfaces Publicas

                    public validarCodigoPrecio validarPrecio;

                    public string codlis_pre
                    {
                        get { return _precios.CODLIS_PRE; }
                        set 
                        {
                            if (agregar == true)
                            {
                                _precios.CODLIS_PRE = value;
                                base.OnPropertyChanged("codlis_pre");
                            }
                        }
                    }

                    public string nomlis_pre
                    {
                        get { return _precios.NOMLIS_PRE; }
                        set 
                        {
                            if (_precios.NOMLIS_PRE != value && agregar==false)
                                actualizar = true;
                            _precios.NOMLIS_PRE = value;
                            base.OnPropertyChanged("nomlis_pre");
                        }
                    }

                    public string aplicaa_pre
                    {
                        get { return _precios.APLICAA_PRE; }
                        set { _precios.APLICAA_PRE = value; base.OnPropertyChanged("aplicaa_pre"); }
                    }

                    public string tiplis_pre
                    {
                        get { return _precios.TIPLIS_PRE; }
                        set { _precios.TIPLIS_PRE = value; base.OnPropertyChanged("tiplis_pre"); }
                    }

                    private bool _actualizar = false;
                    public bool actualizar
                    {
                        get { return _actualizar; }
                        set { _actualizar = value; base.OnPropertyChanged("actualizar"); 
                        }
                    }

                    private bool _eliminar = false;
                    public bool eliminar
                    {
                        get { return _eliminar; }
                        set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
                    }

                    private bool _agregar = false;
                    public bool agregar
                    {
                        get { return _agregar; }
                        set { _agregar = value; base.OnPropertyChanged("agregar"); }
                    }
   
                #endregion

                #region IDataErrorInfo Members

                    string IDataErrorInfo.Error { get { return null; } }

                    string IDataErrorInfo.this[string propertyName]
                    {
                        get { return this.GetValidationError(propertyName); }
                    }

                #endregion

                #region Validation

                    /// <summary>
                    /// Returns true if this object has no validation errors.
                    /// </summary>
                    /// 

                    public bool IsValid
                    {
                        get
                        {
                            foreach (string property in ValidatedProperties)
                                if (GetValidationError(property) != null)
                                    return false;
                            return true;
                        }
                    }

                    static readonly string[] ValidatedProperties = 
                    { 
                        "codlis_pre",
                        "nomlis_pre"
                    };

                    string GetValidationError(string propertyName)
                    {
                        if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                            return null;

                        string error = null;

                        switch (propertyName)
                        {
                            case "codlis_pre":
                                error = this.Validatecodigo();
                                break;
                            case "nomlis_pre":
                                error = this.ValidateNombre();
                                break;
                            default:
                                Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                                break;
                        }
                        return error;
                    }

                    string Validatecodigo()
                    {
                        try
                        {
                            if (codlis_pre==null) { return "Debe ingresar el código de la lista de precios."; }
                            if (codlis_pre != null)
                            { 
                                if (codlis_pre.Length > 2) { return "El código de la lista de precios no puede tener mas de 2 caracteres"; }
                                string error = null;
                                error = validarPrecio(codlis_pre);
                                if (!String.IsNullOrEmpty(error))
                                {
                                    return error;
                                }
                            }
                            return null;
                        }
                        catch (Exception ex) { MessageBox.Show(ex.Message); }
                        return null;
                    }

                    string ValidateNombre()
                    {
                        try
                        {
                            if (nomlis_pre == null) { return "Debe ingresar el nombre de la lista de precios"; }
                            if (nomlis_pre != null)
                            {
                                if (nomlis_pre.Length > 30) { return "El nombre de la lista de precios no puede tener mas de 30 caracteres"; }
                            }
                            return null;
                        }
                        catch (Exception ex) { MessageBox.Show(ex.Message); }
                        return null;
                    }


                #endregion

            }

        #endregion
    }
}
